package com.changzhi.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.changzhi.common.annotation.Verify;
import com.changzhi.common.constans.RedisConstans;
import com.changzhi.common.exception.ServiceException;
import com.changzhi.common.util.IPUtil;
import com.changzhi.common.util.Result;
import com.changzhi.common.util.TokenUtil;
import com.changzhi.ldyl.model.AppVersion;
import com.changzhi.ldyl.model.dto.InviteDto;
import com.changzhi.mapper.AppVersionMapper;
import com.changzhi.service.InviteService;
import com.changzhi.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:邀请用户
 * @author: 小落
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("invite")
public class InviteController {

	@Autowired
	private InviteService inviteService;
	@Autowired
	private RedisUtil redisUtil;
	@Resource
	private AppVersionMapper appVersionMapper;
	@Value("${h5.domain}")
	private String h5Domain;

	/**
	 * 生成二维码
	 * @param inviteDto
	 * @return
	 */
	@Verify(login = false)
	@PostMapping("/createQrCode")
	public Result createQrCode(@RequestBody @Validated InviteDto inviteDto){
		String inviteCode = inviteDto.getInviteCode();
		if(StringUtils.isBlank(inviteCode)){
			return Result.error("邀请码不能为空");
		}
		Map<String, Object> map = redisUtil.get(RedisConstans.INVITE_QR_CODE + inviteCode);
		if(map != null){
			return Result.success(map);
		}
		map = new HashMap<>();
		map.put("url", ImageUtil.createQrCode(h5Domain, inviteCode));
		redisUtil.set(RedisConstans.INVITE_QR_CODE + inviteCode, map, RedisConstans.ONE_YEAR);
		return Result.success(map);
	}


	/**
	 * 生成海报
	 * @param inviteDto
	 * @return
	 */
	@Verify(login = false)
	@PostMapping("/createPoster")
	public Result createPoster(@RequestBody @Validated InviteDto inviteDto){
		String inviteCode = inviteDto.getInviteCode();
		if(StringUtils.isBlank(inviteCode)){
			return Result.error("邀请码不能为空");
		}
		/*String key = RedisConstans.INVITE_POSTER + inviteCode + "_" + 1;
		Map<String, Object> map = redisUtil.get(key);
		if(map != null){
			return Result.success(map);
		}*/
		Map<String, Object> qrCodeMap = redisUtil.get(RedisConstans.INVITE_QR_CODE + inviteCode);
		String qrCodeUrl = (String) qrCodeMap.get("url");
		if(StringUtils.isNotBlank(qrCodeUrl)){
			qrCodeUrl = ImageUtil.createQrCode(h5Domain, inviteCode);
			Map<String, Object> qrCodemap = new HashMap<>();
			qrCodemap.put("url", qrCodeUrl);
			redisUtil.set(RedisConstans.INVITE_QR_CODE + inviteCode, qrCodemap, RedisConstans.ONE_YEAR);
		}
		String str = ImageUtil.createPoster(inviteCode, qrCodeUrl);
		Map<String, Object> map = new HashMap<>();
		map.put("poster1", "data:image/png;base64,"+str);
		return Result.success(map);
	}

	/**
	 * 基本信息
	 * @param inviteDto
	 * @return
	 */
	@Verify(login = false)
	@PostMapping("/getBaseInfo")
	public Result getBaseInfo(@RequestBody @Validated InviteDto inviteDto){
		if(StringUtils.isNotBlank(inviteDto.getToken())){
			inviteDto.setUserId(TokenUtil.getUidByToken(inviteDto.getToken()));
		}
		return Result.success(inviteService.getBaseInfo(inviteDto));
	}

	/**
	 * 其他信息
	 * @param inviteDto
	 * @return
	 */
	@Verify
	@PostMapping("/getOtherInfo")
	public Result getOtherInfo(@RequestBody @Validated InviteDto inviteDto){
		return Result.success(inviteService.getOtherInfo(inviteDto));
	}

	/**
	 * 分享页面
	 * @return
	 */
	@PostMapping("/share")
	public Result share(@RequestBody InviteDto inviteDto, HttpServletRequest request){
		String ip = IPUtil.toIpAddr(request);
		String code = inviteDto.getInviteCode();
		if(StringUtils.isBlank(code)){
			return Result.error("邀请码不能为空");
		}
		long count = redisUtil.incr(RedisConstans.EXTERNAL_INVITE_LINK_ACCESS_COUNT + code);
		redisUtil.expire(RedisConstans.EXTERNAL_INVITE_LINK_ACCESS_COUNT + code, 60L);
		if (count <= 1) {
		} else if (count >= 120) {
			log.error("1分钟内请求相同邀请链接过于频繁, code:{} ip:{} count:{}", code, ip, count);
			return Result.error("系统繁忙，请稍后重试");
		}
		log.warn("methodName:share, code={}, ip={}, agent={}", code, ip);
		return Result.success(inviteService.share(code, ip));
	}

	/**
	 * 兑换奖品
	 * @param inviteDto
	 * @return
	 */
	@Verify
	@PostMapping("/exPrize")
	public Result exPrize(@RequestBody @Validated InviteDto inviteDto){
		return Result.success(inviteService.exPrize(inviteDto));
	}

	/**
	 * 兑换列表
	 * @param inviteDto
	 * @return
	 */
	@Verify
	@PostMapping("/exRecordList")
	public Result exRecordList(@RequestBody @Validated InviteDto inviteDto){
		return Result.success(inviteService.exRecordList(inviteDto));
	}


	/**
	 * 邀请记录列表
	 * @param inviteDto
	 * @return
	 */
	@Verify
	@PostMapping("/inviteList")
	public Result inviteList(@RequestBody @Validated InviteDto inviteDto){
		return Result.success(inviteService.inviteList(inviteDto));
	}

	/**
	 * 邀请人数
	 * @param inviteDto
	 * @return
	 */
	@Verify
	@PostMapping("/inviteSum")
	public Result inviteSum(@RequestBody @Validated InviteDto inviteDto){
		return Result.success(inviteService.inviteSum(inviteDto));
	}

	/**
	 * 奶爸邀请链接访问记录
	 * @param request
	 * @param response
	 */
	@RequestMapping("/down/{code}")
	public void down(@PathVariable String code, HttpServletRequest request, HttpServletResponse response) throws IOException {
		String agent = request.getHeader("user-agent");
		String ip = IPUtil.toIpAddr(request);
		log.warn("methodName:down, code={}, ip={}, agent={}", code, ip, agent);
		if (StringUtils.isBlank(code) || code.length() > 10 || StringUtils.isEmpty(ip)) {
			responseAsDownLinkError(response,"无效的邀请链接");
			return;
		}
		long count = redisUtil.incr(RedisConstans.EXTERNAL_INVITE_LINK_ACCESS_COUNT + code);
		redisUtil.expire(RedisConstans.EXTERNAL_INVITE_LINK_ACCESS_COUNT + code, 60L);
		if (count <= 1) {
		} else if (count >= 120) {
			log.error("1分钟内请求相同邀请链接过于频繁, code:{} ip:{} count:{}", code, ip, count);
			responseAsDownLinkError(response,"系统繁忙，请稍后重试");
			return;
		}
		boolean recordSuc = inviteService.insertVisitRecord(code, ip);
		if (!recordSuc) {
			responseAsDownLinkError(response,"邀请链接已失效");
			return;
		}
		//判断是Android还是ios，重定向到下载地址或者ios应用商店
		if(agent != null){
			if (agent.contains("iPhone") || agent.contains("iPod") || agent.contains("Mac")) {
				response.sendRedirect("itms-apps://itunes.apple.com/app/id1490820119");
				return;
			} else if (agent.contains("Weixin") || agent.contains("WeChat")) {
				response.sendRedirect("https://www.xbyy.live");
				return;
			}
		}
		AppVersion appVersion = appVersionMapper.selectOne(new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getOpenId, "official").last("limit 1"));
		if (appVersion == null) {
			appVersion.setDownloadUrl("https://res.xbyy.live/apk/xiaobai_V3.0.9_124_official.apk");
		}
		response.sendRedirect(CommonUtil.urlEncodeChinese(appVersion.getDownloadUrl()));
	}


	private void responseAsDownLinkError(HttpServletResponse response, String message) throws
			IOException {
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().write(message);
	}

	public static void main(String[] args) {
		System.out.println(TokenUtil.createToken("1295253461415231488", 72));
	}

}
